<?php

declare(strict_types=1);

namespace app\service\user;

use app\model\Org;
use app\model\OrgMember;
use app\model\User;
use app\model\UserIdentity;
use app\model\UserIndividual;
use InvalidArgumentException;
use think\facade\Db;

class IndividualVerificationService
{
    public function getIndividual(int $userId): ?UserIndividual
    {
        return UserIndividual::where('user_id', $userId)->find();
    }

    public function approveIndividual(int $userId, array $options = []): array
    {
        return Db::transaction(function () use ($userId, $options) {
            $individual = UserIndividual::where('user_id', $userId)
                ->lock(true)
                ->find();

            if (!$individual) {
                throw new InvalidArgumentException('尚未提交个人认证资料');
            }

            $now = date('Y-m-d H:i:s');

            $individual->save([
                'status' => 1,
                'verified_at' => $now,
            ]);

            $user = User::where('id', $userId)->lock(true)->find();
            if (!$user) {
                throw new InvalidArgumentException('用户不存在');
            }

            $requestedRegionId = (int) ($options['region_id'] ?? 0);

            $org = $this->ensureBuyerOrg(
                $user,
                $individual,
                $requestedRegionId,
                (int) ($options['approved_by'] ?? 0),
                $now
            );

            $resolvedRegionId = $requestedRegionId > 0
                ? $requestedRegionId
                : ((int) ($org->region_id ?? 0));

            $this->syncBuyerIdentity($user, $org->id, $resolvedRegionId, $now);

            UserRoleManager::ensureRoles($user->id, [[
                'slug' => 'buyer_admin',
                'org_id' => $org->id,
                'region_id' => $resolvedRegionId > 0 ? $resolvedRegionId : null,
            ]]);

            return [
                'individual' => $individual->refresh(),
                'org' => $org->refresh(),
            ];
        });
    }

    public function rejectIndividual(int $userId, string $reason = ''): UserIndividual
    {
        return Db::transaction(function () use ($userId, $reason) {
            $individual = UserIndividual::where('user_id', $userId)
                ->lock(true)
                ->find();

            if (!$individual) {
                throw new InvalidArgumentException('尚未提交个人认证资料');
            }

            $individual->save([
                'status' => 2,
                'verified_at' => null,
            ]);

            UserIdentity::where('user_id', $userId)
                ->where('identity_type', 'buyer')
                ->update([
                    'status' => 0,
                    'verified_at' => null,
                    'remark' => $reason,
                ]);

            return $individual->refresh();
        });
    }

    private function ensureBuyerOrg(
        User $user,
        UserIndividual $individual,
        int $regionId,
        int $approvedBy,
        string $now
    ): Org {
        $identity = UserIdentity::where('user_id', $user->id)
            ->where('identity_type', 'buyer')
            ->lock(true)
            ->find();

        $org = null;
        if ($identity && $identity->org_id) {
            $org = Org::where('id', $identity->org_id)->lock(true)->find();
        }

        $profile = $user->profile;
        $displayName = $individual->real_name ?: ($profile->real_name ?? $profile->nickname ?? $user->phone);
        $orgName = $displayName ? sprintf('%s买家', $displayName) : sprintf('买家%s', substr($user->phone, -4));

        $regionId = $regionId > 0 ? $regionId : ($identity?->region_id ?: null);

        if (!$org) {
            $org = Org::create([
                'name' => $orgName,
                'org_type' => Org::TYPE_BUYER,
                'logo_url' => '',
                'region_id' => $regionId,
                'owner_user_id' => $user->id,
                'inviter_user_id' => $identity?->invited_by,
                'approved_by' => $approvedBy ?: null,
                'approved_at' => $now,
                'status' => 1,
            ]);
        } else {
            $update = [
                'status' => 1,
                'approved_at' => $now,
            ];
            if ($approvedBy > 0) {
                $update['approved_by'] = $approvedBy;
            }
            if ($regionId !== null) {
                $update['region_id'] = $regionId;
            }
            if ($org->owner_user_id === null) {
                $update['owner_user_id'] = $user->id;
            }
            $org->save($update);
        }

        $member = OrgMember::where('org_id', $org->id)
            ->where('user_id', $user->id)
            ->lock(true)
            ->find();

        if ($member) {
            $member->save([
                'member_role' => OrgMember::ROLE_OWNER,
                'status' => 1,
                'joined_at' => $now,
            ]);
        } else {
            OrgMember::create([
                'org_id' => $org->id,
                'user_id' => $user->id,
                'member_role' => OrgMember::ROLE_OWNER,
                'position' => '负责人',
                'status' => 1,
                'joined_at' => $now,
            ]);
        }

        return $org;
    }

    private function syncBuyerIdentity(User $user, int $orgId, ?int $regionId, string $now): void
    {
        $identity = UserIdentity::where('user_id', $user->id)
            ->where('identity_type', 'buyer')
            ->lock(true)
            ->find();

        $payload = [
            'status' => 1,
            'org_id' => $orgId,
            'verified_at' => $now,
        ];

        if ($regionId !== null && $regionId > 0) {
            $payload['region_id'] = $regionId;
        }

        if ($identity) {
            $identity->save($payload);
        } else {
            UserIdentity::create(array_merge([
                'user_id' => $user->id,
                'identity_type' => 'buyer',
            ], $payload));
        }
    }
}
